from multiprocessing import Process, Lock, Manager

import lib, sql

from xdh_logging import initLog

log = initLog("cache")

class _Cache(object):
	_data = Manager().dict()

	def __init__(self):
		pass

	def __repr__(self):
		self.items()
		return _Cache._data.__repr__()

	def __str__(self):
		self.items()
		return _Cache._data.__str__()

	def __unicode__(self):
		self.items()
		return _Cache._data.__unicode__()

	def __len__(self):
		return sql.CacheData.len()

	def __getitem__(self, key):
		if key not in _Cache._data:
			if sql.CacheData.contains(key):
				_Cache._data[key] = sql.CacheData.get(key)
			else:
				raise KeyError("{key} not found.".format(key = key))

		return _Cache._data[key]

	def __setitem__(self, key, value):
		_Cache._data[key] = value

		sql.process(sql.CacheData, "insert", [{"key": key, "value": value}])

	def __delitem__(self, key):
		if key in _Cache._data:
			del _Cache._data[key]

		sql.process(sql.CacheData, "delete", [{"key": key}])

	def iteritems(self):
		for key, value in sql.CacheData.iteritems():
			if key not in _Cache._data:
				_Cache._data[key] = value

			yield (key, value)

	def __iter__(self):
		for key, value in self.iteritems():
			yield key

	def iterkeys(self):
		for key, value in self.iteritems():
			yield key

	def itervalues(self):
		for key, value in self.iteritems():
			yield value

	def __contains__(self, key):
		try:
			self.__getitem__(key)
			return True
		except KeyError:
			return False

	def has_key(self, key):
		return self.__contains__(key)

	def keys(self):
		for key, value in sql.CacheData.iteritems():
			if key not in _Cache._data:
				_Cache._data[key] = value

		return _Cache._data.keys()

	def values(self):
		for key, value in sql.CacheData.iteritems():
			if key not in _Cache._data:
				_Cache._data[key] = value

		return _Cache._data.values()

	def items(self):
		for key, value in sql.CacheData.iteritems():
			if key not in _Cache._data:
				_Cache._data[key] = value

		return _Cache._data.items()

	def clear(self):
		keys = [key for key in self.iterkeys()]

		for key in keys:
			self.__delitem__(key)

	def setdefault(self, key, default = None):
		try:
			return self.__getitem__(key)
		except KeyError:
			self.__setitem__(key, default)
			return default

	def pop(self, key, default = None):
		try:
			ret = self.__getitem__(key)

			self.__delitem__(key)

			return ret

		except KeyError, e:
			if default == None:
				raise e
			else:
				return default

	def popitem(self):
		return self.pop(sql.CacheData.get_one_key())

	def update(self, other):
		for key, value in other.iteritems():
			self.__setitem__(key, other)

	def copy(self):
		return {key: value for key, value in self.iteritems()}


cache = _Cache()
